#include "SignatureGenerator.h"

#include <Assert.h>
#include <QDEBUG>

namespace AliOSS
{
    SignatureGenerator::SignatureGenerator(
        const QString &bucket,
        const QString &accessId,
        const QByteArray &accessSecert)
        : bucket(bucket), accessId(accessId), accessSecert(accessSecert)
    {

    }

    SignatureGenerator::~SignatureGenerator()
    {

    }

	QString SignatureGenerator::once(
		const QString &verb,
		const QString &datetimestr,
		const QString &filePath,
		const QString &md5InBase64/*=QString()*/, const QMap<QString, QByteArray> ossHeaders/*=QMap<QString,QByteArray>()*/,
		const QString &contentType/*=QString()*/)
	{
		QString signatureStr = "[VERB]\n"
			"[contentMD5]\n"
			"[contentType]\n"
			"[date]\n"
			"[canonicalizedOSSHeaders]"
			"[canonicalizedResource]";
		signatureStr.replace("[VERB]", verb);
		signatureStr.replace("[contentMD5]", md5InBase64);
		signatureStr.replace("[contentType]", contentType);

		signatureStr.replace("[date]", datetimestr);
		QString ossHeaderStr;
		for (auto i = ossHeaders.begin(), e = ossHeaders.end();
			i != e;
			i++)
		{
			QString k = i.key();
			assert(k == k.toLower());
			QString v = i.value();
			ossHeaderStr += k + ':' + v + '\n';
		};

		signatureStr.replace("[canonicalizedOSSHeaders]", ossHeaderStr);
		signatureStr.replace("[canonicalizedResource]", "/[bucket]/[object]");
		signatureStr.replace("[bucket]", bucket);
		signatureStr.replace("[object]", filePath);

#ifdef _DEBUG
		qDebug().noquote() << "str2sign : " << signatureStr;
		qDebug().noquote() << "hex2sign : " << signatureStr.toUtf8().toHex().toUpper();
#endif // _DEBUG
		return QMessageAuthenticationCode::hash(signatureStr.toUtf8(), accessSecert, QCryptographicHash::Sha1).toBase64();
	}
}
